/***************************************************************************************************
  *Copyright(C),2015-2020,Sumscope
  *FileName	    :  NatBondFutureToolsParam
  *Author	    :  Givins.zhu
  *Version	    :  1.0
  *Date		    :  2015/08/21
  *Desc		    :  data model
  *Function     :  bond list calculate param
  *History	    :  
  *Email        :  Givins.zhu@sumscope.com  
  *Requirement  :  
***************************************************************************************************/
#pragma once
#define NOMINMAX
#include "tfbondlib.h"
#include "tfBondInfo.h"
#include "NatDebtDataModel.h"
#ifdef WIN32
#include <corecrt.h>
#endif
#include <core/Utility.h>
#include <core/core.h>
#include <core/strings/string_util.h>
#include <uam/UserAccountManager.h>
#include <bondlib/BondContainer.h>
#include <vector>
#include <utility>

#define NAT_DEBT_ERROR_NUMBER (-999.00)
#define INVALID_NATDEBT_DOUBLE -999

//国债期货价格属性
class S_TFBONDLIB_EXPORT CNatCalcuPrice{
private:
	/*覆盖类型*/
	enum emCover{
		cover_Bid = 0,
		cover_Ofr,
		cover_Deal
	};
	/*最优算法中,新加的是否更优*/
	bool needCover(emCover cover, const CNatCalcuPrice& prcCover){
		if (cover == cover_Deal){
			return prcCover.m_tTime > m_tTime;
		}
		else if (prcCover.m_cPrice[0] != '\0' && strcmp(prcCover.m_cPriceState, "0") != 0){
			if (strcmp(m_cPriceState, "0") == 0 || m_cPrice[0] == '\0' || strcmp(m_cPrice, "Bid") == 0 || strcmp(m_cPrice, "Ofr") == 0) return true;
			if (cover == cover_Bid){
				return  strcmp(prcCover.m_cPrice, "Bid") != 0 && atof(prcCover.m_cPrice) - atof(m_cPrice) < -0.00001;
			}
			else{
				return  strcmp(prcCover.m_cPrice, "Ofr") != 0 && atof(prcCover.m_cPrice) - atof(m_cPrice) > 0.00001;
			}
		}
		return false;
	}
public:
	CNatCalcuPrice(){
		Initial();
	}

	void operator = (const CNatCalcuPrice& obj){
		m_dbIRR = obj.m_dbIRR;
		m_dbCleanPrice = obj.m_dbCleanPrice;
		m_dbYTM = obj.m_dbYTM;
		m_dbInitialPrice = obj.m_dbInitialPrice;
		m_dbBasis = obj.m_dbBasis;
		m_tTime = obj.m_tTime;
		m_nBroker = obj.m_nBroker;
		FIELDCOPY(m_cPrice, obj.m_cPrice);
		FIELDCOPY(m_cPriceState, obj.m_cPriceState);
		FIELDCOPY(m_cVolumn, obj.m_cVolumn);
		FIELDCOPY(m_cCompanyName, obj.m_cCompanyName);
	}

	void Initial(){
		memset(m_cPrice, 0, sizeof(m_cPrice));
		memset(m_cPriceState, 0, sizeof(m_cPriceState));
		memset(m_cVolumn, 0, sizeof(m_cVolumn));
		memset(m_cCompanyName, 0, sizeof(m_cCompanyName));
		m_tTime = 0;
		m_nBroker = -1;
		m_dbIRR = m_dbCleanPrice = m_dbYTM = m_dbInitialPrice = m_dbBasis = NAT_DEBT_ERROR_NUMBER;
	}

	bool bidCover(const CNatCalcuPrice& cover){
		if (!needCover(cover_Bid, cover)) return false;
		*this = cover;
		return true;
	}
	bool ofrCover(const CNatCalcuPrice& cover){
		if (!needCover(cover_Ofr, cover)) return false;
		*this = cover;
		return true;
	}
	bool dealCover(const CNatCalcuPrice& cover){
		if (!needCover(cover_Deal, cover)) return false;
		*this = cover;
		return true;
	}

	char   m_cPrice[12];
	char   m_cPriceState[3];
	char   m_cVolumn[64];		 //报价量
	char   m_cCompanyName[128];  //CFETS公司名
	double  m_dbIRR;
	double  m_dbCleanPrice;//净价
	double  m_dbYTM;//收益率
	double  m_dbInitialPrice;//初始价格
	double  m_dbBasis;//基差
	time_t  m_tTime;

	int  m_nBroker;//属于哪个broker;
};

//默认计算值
class S_TFBONDLIB_EXPORT CNatIRRSingle{//一个计算出来的数据
public:
	CNatIRRSingle():m_strCombKey(""){
		Initial();
	}
	void Initial(){//初始化
		m_strCombCode = "";
		m_unDelivery_Date = 0;
		m_nBondIndex = m_nBrokerID = -1;
		m_tMaxTime = 0;
		m_dbConvertFactor = m_dbAccruedAmount = m_dbCashPrice = NAT_DEBT_ERROR_NUMBER;
		InitialBest();
		m_PrcDeal.Initial(); 
		m_PrcEst.Initial(); 
		m_PrcMid.Initial(); 
		m_PrcLastestDeal.Initial();
	}
	void InitialBest(){
		m_tMaxTime = 0;
		m_PrcBid.Initial();
		m_PrcOfr.Initial();
	}
	time_t GetMaxTime() const
	{
		if (m_tMaxTime != std::max(m_PrcBid.m_tTime, m_PrcOfr.m_tTime)){
			int xxx = 0;
		}
		return std::max(m_tMaxTime, m_PrcDeal.m_tTime);
	}
	void SetMaxTime(time_t tTime){
		m_PrcBid.m_tTime = m_PrcOfr.m_tTime = m_tMaxTime = tTime;
	}
	void Print();
	void Copy(const CNatIRRSingle& natSgl);

	//最优报价覆盖 所有报价  包括bid,ofr,deal,lastdeal
	bool CoverReport(const CNatIRRSingle& sglSource){
		bool bMax = false;
		if(m_PrcBid.bidCover(sglSource.m_PrcBid)) bMax = true;
		if(m_PrcOfr.ofrCover(sglSource.m_PrcOfr)) bMax = true;
		m_PrcDeal.dealCover(sglSource.m_PrcDeal);
		m_PrcLastestDeal.dealCover(sglSource.m_PrcLastestDeal);
		if (bMax) m_tMaxTime = std::max(m_PrcBid.m_tTime, m_PrcOfr.m_tTime);
		return true;
	}
	//能否计算mid价格,需要初始化数据
	bool EnableCalMidPrice(){
		m_PrcMid.m_dbBasis = m_PrcMid.m_dbIRR = m_PrcMid.m_dbYTM = m_PrcMid.m_dbCleanPrice = NAT_DEBT_ERROR_NUMBER;
		return ((m_PrcOfr.m_cPrice[0] != '\0') && (strcmp(m_PrcOfr.m_cPrice, "0") != 0)
			&& (strcmp(m_PrcOfr.m_cPrice, "Ofr") != 0) && strcmp(m_PrcOfr.m_cPriceState, "0") != 0
			&& (m_PrcBid.m_cPrice[0] != '\0') && (strcmp(m_PrcBid.m_cPrice, "0") != 0)
			&& (strcmp(m_PrcBid.m_cPrice, "Bid") != 0) && strcmp(m_PrcBid.m_cPriceState, "0") != 0
			&& m_dbConvertFactor > 0.001);
	}
public:
	std::string m_strCombKey;
	std::string m_strCombCode;
	int     m_nBrokerID;
	int		m_nBondIndex;
	time_t  m_tMaxTime;
	UINT	m_unDelivery_Date;
	float   m_dbConvertFactor;//转换因子
	double  m_dbAccruedAmount/*应计利息*/, m_dbCashPrice/*期间付息*/;
	CNatCalcuPrice m_PrcBid, m_PrcOfr, m_PrcDeal, m_PrcEst, m_PrcMid, m_PrcLastestDeal;
};

class S_TFBONDLIB_EXPORT CNatToolsIRR{//需要获取的IRR数据
public:
	CNatToolsIRR(std::string strTFID = "") : m_strTFId(strTFID) , m_dbLastPrice(0.0f) ,m_dbSettlementPrice(0.0f),m_unDelivery_Date(0){}
	virtual ~CNatToolsIRR(){}
public:
	CNatIRRSingle m_irrMax;
	CNatIRRSingle m_irrSecond;
	std::string m_strTFId;
	double  m_dbLastPrice;//合约最新价
	double  m_dbSettlementPrice;//昨结
	UINT	m_unDelivery_Date;//
};

class S_TFBONDLIB_EXPORT CNatToolsBrokP{//Broker参数
public:
	CNatToolsBrokP(int nBrok):m_nBrokerID(nBrok){}
	virtual ~CNatToolsBrokP(){}
public:
	int m_nBrokerID;
	map<std::string,CNatIRRSingle> m_mapBond;//现券
	map<std::string,CNatIRRSingle> m_mapCumstomBond;//自选券
	void InsertBond(const xQBRefBond_c& refbond);
	/*插入自选券*/
	bool InsertCumstomBond(const char* cBondKey , const char* cListMarket);
	//删除自选
	void DelCumstomBond(const char* cBondKey , const char* cListMarket);
};

class S_TFBONDLIB_EXPORT CNatToolsTFP{//合约参数
public:
	CNatToolsTFP():m_strTFId(""){}
	~CNatToolsTFP(){}
public:
	void InitialTF(std::string strTFid,vector<CBrokerUnit>& broker){
		m_strTFId = strTFid;
		int nSz = broker.size();
		for(int nL = 0 ; nL < nSz ; nL ++){
			CNatToolsBrokP toolsBrok(broker[nL].m_brokerID);
			m_vctBroker.push_back(toolsBrok);
		}
	}
public:
	std::string m_strTFId;//合约Id;
	std::vector<CNatToolsBrokP> m_vctBroker;
};

class S_TFBONDLIB_EXPORT CNatBondFutureToolsParam{//最廉可交割券计算参数
public:
	CNatBondFutureToolsParam();
	virtual ~CNatBondFutureToolsParam();
	void InitialTFBroker(std::vector<CBrokerUnit>& broker , std::vector<CFutureInfo>& tf);
	void Clear();
	const CNatToolsTFP* GetTFParamFromID(const std::string tfID); //获取对应合约数据
public:
	std::vector<CNatToolsTFP> m_vctTF;
};

/*自选券信息*/
class S_TFBONDLIB_EXPORT CNatDebtTFCumstomBond
{
public:
	map<std::string/*comBondkey*/,CNatIRRSingle> m_MapKey;
	
	void InsertBond(const std::list<TW_BOND>& lstBond){
		CNatIRRSingle sgl;
		std::string strCombondKey;
		for(auto itrBd = lstBond.begin(); itrBd != lstBond.end(); ++itrBd){
			strCombondKey = qb::base::string_format("%s.%s",itrBd->m_BondKey,itrBd->m_ListedMarket);
			AddBond(strCombondKey);
		}
	}

	void DelBond(std::string& strCombondKey){//删除
		std::map<std::string,CNatIRRSingle>::const_iterator itr = m_MapKey.find(strCombondKey);
		if(itr != m_MapKey.end()) m_MapKey.erase(itr);
	}

	void AddBond(std::string& strCombondKey){//添加
		int bondIndex = CBondContainer::instance().GetBondIndex(strCombondKey.c_str());
		if(CBondContainer::instance().IsValidIndex(bondIndex))
		{
			CNatIRRSingle sgl;
			sgl.m_strCombKey = strCombondKey;
			sgl.m_nBondIndex = bondIndex;
			m_MapKey.insert(std::pair<std::string,CNatIRRSingle>(strCombondKey,sgl));
		}
	}
};

class S_TFBONDLIB_EXPORT CNatDebtTFCumstom//自选券
{
public:
	void Initial(vector<CFutureInfo>& tf){
		CNatDebtTFCumstomBond bond;
		int nCnt = tf.size();
		std::string strTFId;
		for(int nL = 0 ; nL < nCnt ; nL ++){
			strTFId = qb::base::string_format("%s",tf[nL].m_TF_ID);
			m_TFCumstomBond.insert(std::pair<std::string,CNatDebtTFCumstomBond>(strTFId,bond));
		}
	}

	void Clear(){
		m_TFCumstomBond.clear();
	}

	void InsertBond(xNatDebtCustomBondAck_c * ack){
		if(!ack) return;
		std::string strTFID;
		for(std::list<xNatDebtCustomBondUnit_c>::const_iterator itr = ack->m_List.begin();
			itr != ack->m_List.end();  ++itr){
			strTFID = qb::base::string_format("%s",itr->m_InstrumentID);
			if(m_TFCumstomBond.find(strTFID) != m_TFCumstomBond.end()){
				CNatDebtTFCumstomBond& TFBond = m_TFCumstomBond[strTFID];
				TFBond.InsertBond(itr->m_List);
			}
		}
	}

	void DelBond(std::string& strTFID, std::string& strCombondKey){//删除
		if(m_TFCumstomBond.find(strTFID) != m_TFCumstomBond.end()){
			m_TFCumstomBond[strTFID].DelBond(strCombondKey);
		}
	}

	void AddBond(std::string& strTFID, std::string& strCombondKey){//添加
		if(m_TFCumstomBond.find(strTFID) != m_TFCumstomBond.end()){
			m_TFCumstomBond[strTFID].AddBond(strCombondKey);
		}
	}

	map<std::string/*合约代码*/,CNatDebtTFCumstomBond>  m_TFCumstomBond;//自选券
};

class S_TFBONDLIB_EXPORT CNatDebtDouble{
public:
	CNatDebtDouble(){
		Initial();
	}
	void operator = (const double& dbObj){
		Initial();
		m_dbObj = dbObj;
		if (!VerifyValidCalculate(dbObj)) return;
		std::string strTemp = qb::base::string_format("%.3f", dbObj);
		size_t pos = strTemp.find_first_of(".");
		if (pos != std::string::npos){
			std::string strLeft = strTemp.substr(0, pos);
			std::string strRight = strTemp.substr(pos+1, strTemp.length()-pos);
			m_nLeft = std::stoi(strLeft);
			m_nRight = std::stoi(strRight);
		}
	}
	bool operator < (const CNatDebtDouble& dbObj) const{
		if (m_nLeft == dbObj.m_nLeft){
			return m_nRight < dbObj.m_nRight;
		}
		else {
			return m_nLeft < dbObj.m_nLeft;
		}
	}
	bool operator > (const CNatDebtDouble& dbObj) const{
		if (m_nLeft == dbObj.m_nLeft){
			return m_nRight > dbObj.m_nRight;
		}
		else {
			return m_nLeft > dbObj.m_nLeft;
		}
	}
	bool operator == (const CNatDebtDouble& dbObj) const{
		return (m_nLeft == dbObj.m_nLeft && m_nRight == dbObj.m_nRight);
	}
	void Initial(){
		m_dbObj = NAT_DEBT_ERROR_NUMBER;
		m_nLeft = m_nRight = -INVALID_NATDEBT_DOUBLE;
	}
	double m_dbObj;

	int   m_nLeft; //小数点左边
	int   m_nRight;//小数点右边
};

/*用来计算的参数*/
class S_TFBONDLIB_EXPORT CNatDebtCalParam{
public:
	CNatDebtCalParam(){
		Initial();
	}
	CNatDebtCalParam(float fFac,double dbBondPrc,double dbTfPrc, std::string& strbondKey, std::string& strTfID){
		Initial(fFac, dbBondPrc, dbTfPrc, strbondKey, strTfID);
	}
	void Initial(float fFac = NAT_DEBT_ERROR_NUMBER, double dbPrc = NAT_DEBT_ERROR_NUMBER, double dbTfPrc = NAT_DEBT_ERROR_NUMBER, std::string strbondKey = "", std::string strTfID = ""){
		m_fFactor = fFac;
		m_dbPrice = dbPrc;
		m_dbTFPrice = dbTfPrc;
		m_dbIRR = m_dbYTMPrc = m_dbCleanPrc = m_dbBasicPrc  = m_dbCashPrice = m_dbAccruedAmount = NAT_DEBT_ERROR_NUMBER;
		m_strBondKey = strbondKey;
		m_strTFId = strTfID;
	}
	float  m_fFactor;
	double m_dbPrice;
	double m_dbYTMPrc;
	double m_dbIRR;
	double m_dbCleanPrc;
	double m_dbBasicPrc;
	double m_dbTFPrice;
	double m_dbCashPrice;
	double m_dbAccruedAmount;

	std::string m_strBondKey;
	std::string m_strTFId;
};


class S_TFBONDLIB_EXPORT CNatDebtCalPrice{

public:
	CNatDebtCalPrice(){ ; }
	bool operator < (const CNatDebtCalPrice& obj) const{
		if (m_Delivery_Date == obj.m_Delivery_Date){
			if (m_stBondkey == obj.m_stBondkey){
				if (m_dbTFPrice == obj.m_dbTFPrice){
					return m_dbBondPrice < obj.m_dbBondPrice;
				}
				else{
					return m_dbTFPrice < obj.m_dbTFPrice;
				}
			}
			else{
				return m_stBondkey < obj.m_stBondkey;
			}
		}
		else{
			return m_Delivery_Date < obj.m_Delivery_Date;
		}
	}
	void PrintString(const char* addString){
// 		if (BOOLTEST(kProfileExchangeOutputRealTimer)){
// 			time_t tnowtime, tServTime = AfxGetBondContainer().GetServerTime();
// 			time(&tnowtime);
// 			QString strPrint;
// 			strPrint = QString::asprintf("[Test--For--NAT]-- key:%s ytm:%.4f tfDate:%d tfPrc:%.4f clean:%.4f irr:%.4f basis:%.4f %s"
// 				, m_stBondkey.c_str(), m_dbYTM, m_Delivery_Date, m_dbTFPrice.m_dbObj, m_dbClean, m_dbIRR, m_dbBsisPrice, addString);
// 			//OutputDebugString(strPrint);
// 			logInfo(strPrint.toStdString().c_str());
// 		}
	}
public:
	/************************************************************************/
	/* KEY                           */
	/************************************************************************/
	int    m_Delivery_Date;
	CNatDebtDouble m_dbTFPrice;
	CNatDebtDouble m_dbBondPrice;
	string m_stBondkey;

	/*value*/
	double m_dbYTM;/**/
	double m_dbClean;
	double m_dbIRR;
	double m_dbBsisPrice;
	double m_dbCashPrice;
	double m_dbAccruedAmount;
	double m_dbTFYTM; //add by givins.zhu 2019/11/14  for 期货对应的利率
};

class S_TFBONDLIB_EXPORT CNatDebtCalCache{
public:
	static CNatDebtCalCache& GetInstance();
	void Clear();
	void AddPrice(CNatDebtCalPrice& price);
	bool GetPrice(CNatDebtCalPrice& price);

private:
	CNatDebtCalCache();

	/*缓存的日期 YYYYMMDD*/
	int m_nCacheDate;

	/*数据缓存  建立在计算出结果的情况下*/
	std::set<CNatDebtCalPrice>  m_setPrice;
	//map<CNatDebtCalPrice, int> m_mapPrice;
};